
#include "type.h"

uint32_t __ratio(uint32_t a_reference,
					   uint32_t a_start, uint32_t a_end,
					   uint32_t b_start, uint32_t b_end)
{
	uint32_t b_reference;

	//(a_reference-a_start)/(a_end-a_start) = (b_reference-b_start)/(b_end-b_start)
	//b_reference = ((a_reference-a_start)*(b_end-b_start))/(a_end-a_start)+b_start
//	printf("\r\n------->%d, %d, %d, %d, %d\r\n", a_reference, a_start, a_end, b_start, b_end);
	if(a_start >= a_end){
		a_reference = (a_reference-a_start);
		a_start = (a_start-a_end);
	}
	else{
		a_reference = (a_reference-a_start);
		a_start = (a_end-a_start);
	}

	if(b_start >= b_end){
		b_reference = b_start-(((b_start-b_end)*a_reference)/a_start);
	}
	else{
		b_reference = (((b_end-b_start)*a_reference)/a_start)+b_start;
	}
//	printf("b_reference %d\r\n",b_reference);
	return b_reference;
}


/*******************************************************
char *X_itoa(int value, char *string, int radix)
{
    char tmp[33];
    char *tp = tmp;
    int i;
    unsigned v;
    int sign;
    char *sp;
    if (radix > 36 || radix <= 1)
    {
        // __set_errno(EDOM);
        return 0;
    }
    sign = (radix == 10 && value < 0);
    if (sign)
        v = -value;
    else
        v = (unsigned)value;
    while (v || tp == tmp)
    {
        i = v % radix;
        v = v / radix;
        if (i < 10)
            *tp++ = i + '0';
        else
            *tp++ = i + 'a' - 10;
    }
    if (string == 0)
        string = (char *)malloc((tp - tmp) + sign + 1);
    sp = string;
    if (sign)
        *sp++ = '-';
    while (tp > tmp)
        *sp++ = *--tp;
    *sp = 0;
    return string;
}
*******************************************************/

void __itoa(uint8_t* string, uint8_t* string_len, int32_t value, uint8_t radix, uint8_t is_signed)
{
    uint8_t i;
    uint32_t v;
    uint8_t sign;

	if(!is_signed){
		sign = 0;
		v = (uint32_t)value;
	}
	else{
		sign = (radix == 10 && value < 0);
		if (sign)
			v = -value;
		else
			v = (uint32_t)value;
	}

	(*string_len) = 0;
    while(1){
        i = v % radix;
        v = v / radix;
        if (i < 10){
            string[(*string_len)++] = i + '0';
        }
        else{
            string[(*string_len)++] = i + 'a' - 10;
        }
		if(v == 0){
			break;
		}
    }

	if(sign){
		string[(*string_len)++] = '-';
	}
	if(radix == 16){
		string[(*string_len)++] = 'x';
		string[(*string_len)++] = '0';
	}
	if(radix == 2){
		string[(*string_len)++] = 'b';
		string[(*string_len)++] = '0';
	}
}

uint8_t __include_check(uint8_t* buff, uint8_t buff_len, uint8_t obj)
{
	uint8_t i = 0;
	while(1){
		if(buff[i] == obj){
			buff_len = 1;
			break;
		}
		if(i == buff_len-1){
			buff_len = 0;
			break;
		}
		i++;
	}
	return buff_len;
}

//Within a range (range_start -> range_end, include range_start range_end they self),
//start from a starting value (begin), increase a certain value (add).
//If the preset range is exceeded in the increasing process,
//it will back to the starting value of the range (range_start) and continue to increase.
//returns the final value when increasing process was finish
//e.g
//range_start                 range_end
//          3  4  5  6  7  8  9
//add = 8      4 begin        (add == 8)
//add--           5           (add == 7)
//add--              6        (add == 6)
//...
//add--                      9(add == 3)
//add--     3 back to the starting value
//add--        4              (add == 1)
//add == 0        5
//return 5
uint8_t __cycle_increase(uint8_t begin, uint8_t add,
						uint8_t range_start, uint8_t range_end)
{
	if((range_start > begin)
		||(range_end < begin)
		||(range_start >= range_end)){
		return begin;
	}

//	(((begin - range_start) + add) % ((range_end - range_start) + 1)) + range_start;
	begin = (begin - range_start) + add;
	range_end = (range_end - range_start) + 1;
	begin = begin % range_end;
	begin = begin + range_start;

	return begin;
}

int __days_of_month(int year, int month)
{
    switch(month)
    {
        case 4:
        case 6:
        case 9:
        case 11:
            return 30;
        case 2:
            if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0)
                return 29;
            else
                return 28;
        default:
            return 31;
    }
}

uint8_t ___get_unit(uint32_t decimal, uint8_t unit)
{
    uint8_t ret;
    switch(unit){
    case 0:
        ret = ((decimal%10)/1);
        break;
    case 1:
        ret = ((decimal%100)/10);
        break;
    case 2:
        ret = ((decimal%1000)/100);
        break;
    case 3:
        ret = ((decimal%10000)/1000);
        break;
    case 4:
        ret = ((decimal%100000)/10000);
        break;
    case 5:
        ret = ((decimal%1000000)/100000);
        break;
    default:
        ret = 10;
        break;
    }

    return ret;
}

uint8_t ___get_unit(uint16_t decimal , uint8_t unit)
{
    uint8_t ret;
    uint16_t num = decimal ;

    if((decimal  < 10000)&&(unit == 4)){
        return 10;
    }
    ret = 0;
    while (num >= 10000)
    {
        num -= 10000;
        ret++;
    }
    if(unit == 4){
        return ret;
    }

    if((decimal  < 1000)&&(unit == 3)){
        return 10;
    }
    ret = 0;
    while (num >= 1000)
    {
        num -= 1000;
        ret++;
    }
    if(unit == 3){
        return ret;
    }

    if((decimal  < 100)&&(unit == 2)){
        return 10;
    }
    ret = 0;
    while (num >= 100)
    {
        num -= 100;
        ret++;
    }
    if(unit == 2){
        return ret;
    }

    if((decimal  < 10)&&(unit == 1)){
        return 10;
    }
    ret = 0;
    while (num >= 10)
    {
        num -= 10;
        ret++;
    }
    if(unit == 1){
        return ret;
    }

    if((decimal  < 1)&&(unit == 0)){
        return 10;
    }
    ret = 0;
    while (num >= 1)
    {
        num -= 1;
        ret++;
    }
    if(unit == 0){
        return ret;
    }
    return 10;
}

// volatile uint8_t timer_5ms = 0;
// void timer_irq(void)
// {
// 	timer_5ms++;
// }


// void test(void)
// {
// 	static volatile uint8_t timer = 0;
// 	while(1){
// 		if((uint8_t)(timer_5ms - timer) >= 100){		//注意强转
// 			timer = timer_5ms;
// 		}
// 	}
// }

/******************************************************
BANDGAP_v  -> 定值
BANDGAP_ad-> 测得
TARGET_ad -> 测得

TARGET_v / TARGET_ad = BANDGAP_v / BANDGAP_ad ->
TARGET_v = TARGET_ad * BANDGAP_v / BANDGAP_ad
******************************************************/
// #define BANDGAP_VOLT	12
// //TARGET_v = TARGET_ad * BANDGAP_v / BANDGAP_ad
// uint8_t adc_get_volt(uint8_t channel)
// {
// 	uint16_t BandGapAD;
// 	uint16_t targetAD;

// 	Enable_ADC_BandGap;
// 	clr_ADCF;
// 	set_ADCS;																	// Each time ADC start trig signal
// 	while(ADCF == 0);
// 	BandGapAD =  ADCRH;
// 	BandGapAD <<=  8;
// 	BandGapAD |=  ADCRL<<4;
// 	BandGapAD >>= 4;

// 	switch(channel){
// 		case 0:
// 			Enable_ADC_AIN0;
// 			break;
// 		case 1:
// 			Enable_ADC_AIN1;
// 			break;
// 		case 2:
// 			Enable_ADC_AIN2;
// 			break;
// 		case 3:
// 			Enable_ADC_AIN3;
// 			break;
// 		case 4:
// 			Enable_ADC_AIN4;
// 			break;
// 		case 5:
// 			Enable_ADC_AIN5;
// 			break;
// 		case 6:
// 			Enable_ADC_AIN6;
// 			break;
// 		case 7:
// 			Enable_ADC_AIN7;
// 			break;
// 		default:
// 			Enable_ADC_BandGap;
// 			break;
// 	}
// 	clr_ADCF;
// 	set_ADCS;																	// Each time ADC start trig signal
// 	while(ADCF == 0);
// 	targetAD =  ADCRH;
// 	targetAD <<=  8;
// 	targetAD |=  ADCRL<<4;
// 	targetAD >>= 4;

// 	targetAD = targetAD*BANDGAP_VOLT;
// 	targetAD = targetAD/BandGapAD;

// 	return targetAD;
// }

uint8_t Cal_XOR_Check_Sum(uint8_t *dat, uint8_t length)
{
	uint8_t i;
	uint8_t result;
	result = 0;
	for(i = 0; i < length; i++)
	{
		result = result ^ dat[i];
	}
	return result;
}

//#include <time.h>
// void test_time(void)
// {
//     time_t timep;
//     time (&timep);
//     printf("%s", asctime(gmtime(&timep)));
// }
//localtime mktime